package com.cardone.persistent.builder;

import java.util.Map;

import lombok.NonNull;

/**
 * 对象映射生成器
 * 
 * @author yaoht
 */
public interface ModelBuilder {

	/**
	 * 常量枚举
	 * 
	 * @author yaoht
	 * 
	 */
	public enum Constants {
		/**
		 * 全部
		 */
		all,

		/**
		 * 开始行数
		 */
		beginRowNum("begin__row__num"),

		/**
		 * 总合
		 */
		count,

		/**
		 * 默认键值前缀名称
		 */
		defaultKeyPrefix("where__and__eq"),

		/**
		 * 默认键值后缀名称
		 */
		defaultKeySuffix("value"),

		/**
		 * 默认间隔
		 */
		defaultSimpleparator("__"),

		/**
		 * 删除
		 */
		delete,

		/**
		 * 结束行数
		 */
		endRowNum("end__row_num"),

		/**
		 * 创建
		 */
		insert,

		/**
		 * 最大
		 */
		max,

		/**
		 * 最小
		 */
		min,

		/**
		 * 读取字段标识
		 */
		objectId("object__id"),

		/**
		 * 排序
		 */
		orderBy("order__by"),

		/**
		 * 选择
		 */
		select,

		/**
		 * 默认忽略属性数组
		 */
		serialVersionUID,

		/**
		 * 更新
		 */
		update,

		/**
		 * 并且之间
		 */
		whereAndBetween("where__and__between"),

		/**
		 * 并且等于
		 */
		whereAndEq("where__and__eq"),

		/**
		 * 并且不等于
		 */
		whereAndNq("where__and__nq"),

		/**
		 * 或者等于
		 */
		whereOrEq("where__or__eq"),

		/**
		 * 或者不等于
		 */
		whereOrNq("where__and__nq");

		/**
		 * string值
		 */
		private String stringValue;

		/**
		 * 值
		 */
		private Object value;

		/**
		 * 构建
		 */
		private Constants() {
			this.stringValue = this.name();
		}

		/**
		 * 构建
		 * 
		 * @param value
		 *            值
		 */
		private Constants(Object value) {
			this.value = value;
		}

		/**
		 * 构建
		 * 
		 * @param stringValue
		 *            string值
		 */
		private Constants(String stringValue) {
			this.stringValue = stringValue;
		}

		/**
		 * 获取string值
		 * 
		 * @return string值
		 */
		public String stringValue() {
			if (this.stringValue == null) {
				if (this.value == null) {
					return this.name();
				}

				if (this.value instanceof String) {
					return this.value(String.class);
				}
			}

			return this.stringValue;
		}

		/**
		 * 获取T值
		 * 
		 * @param requiredType
		 *            T类型
		 * @return T值
		 */
		@SuppressWarnings("unchecked")
		public <T> T value(@NonNull Class<T> requiredType) {
			if (requiredType.isInstance(this.value)) {
				return (T) this.value;
			}

			return null;
		}
	}

	/**
	 * 对象映射生成
	 * 
	 * @return 对象映射
	 */
	Map<String, Object> build();

	/**
	 * 填充
	 * 
	 * @param keys
	 *            键数组
	 * @param value
	 *            值
	 * @return 对象映射生成器
	 */
	ModelBuilder put(final String[] keys, final Object value);

	/**
	 * 充值扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param kvMap
	 *            键值映射
	 * @param keySuffix
	 *            键后缀名称
	 * @return 对象映射生成器
	 */
	ModelBuilder putExtend(final String keyPrefix, final Map<String, Object> kvMap, final String keySuffix);

	/**
	 * 充值扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keyBase
	 *            键名称
	 * @param keySuffix
	 *            键后缀名称
	 * @param value
	 *            值
	 * @return 对象映射生成器
	 */
	ModelBuilder putExtend(final String keyPrefix, final String keyBase, final String keySuffix, final Object value);

	/**
	 * 充值扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keyBases
	 *            键名称集合
	 * @param keySuffix
	 *            键后缀名称
	 * @param value
	 *            值
	 * @return 对象映射生成器
	 */
	ModelBuilder putExtend(final String keyPrefix, final String[] keyBases, final String keySuffix, final Object value);

	/**
	 * 填充类型或对象字段
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keySuffix
	 *            键后缀名称
	 * @param o
	 *            对象
	 * @param c
	 *            类型
	 * @return 对象映射生成器
	 */
	ModelBuilder putObjectField(final ModelArgs modelArgs);

	/**
	 * 充值true值
	 * 
	 * @param keys
	 *            键数组
	 * @return 对象映射生成器
	 */
	ModelBuilder putTrue(final String... keys);

	/**
	 * 充值true值扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keyBases
	 *            键基本名称
	 * @return 对象映射生成器
	 */
	ModelBuilder putTrueExtend(final String keyPrefix, final String... keyBases);

	/**
	 * 移除扩展
	 * 
	 * @param keys
	 *            键数组
	 * @return 对象映射生成器
	 */
	ModelBuilder remove(final String... keys);

	/**
	 * 移除扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keyBase
	 *            键基本名称
	 * @param keySuffix
	 *            键后缀名称
	 * @return 对象映射生成器
	 */
	ModelBuilder removeExtend(final String keyPrefix, final String keyBase, final String keySuffix);

	/**
	 * 移除扩展
	 * 
	 * @param keyPrefix
	 *            键前缀名称
	 * @param keyBases
	 *            键基本名称集合
	 * @param keySuffix
	 *            键后缀名称
	 * @return 对象映射生成器
	 */
	ModelBuilder removeExtend(final String keyPrefix, final String[] keyBases, final String keySuffix);

	/**
	 * 设置
	 * 
	 * @param defaultKeyPrefix
	 *            默认键值前缀名称
	 */
	ModelBuilder setDefaultKeyPrefix(final String defaultKeyPrefix);

	/**
	 * 设置
	 * 
	 * @param defaultKeySuffix
	 *            默认键值后缀名称
	 */
	ModelBuilder setDefaultKeySuffix(final String defaultKeySuffix);

	/**
	 * 设置
	 * 
	 * @param defaultSimpleparator
	 *            默认间隔
	 */
	ModelBuilder setDefaultSimpleparator(final String defaultSimpleparator);
}